package com.kehutong.charge.app;

import com.kehutong.charge.dto.ChargeBillItemAppDTO;
import com.kehutong.charge.entity.*;
import com.kehutong.charge.service.*;
import com.kehutong.charge.util.CommonClient;
import com.kehutong.charge.util.CommonUtil;
import com.kehutong.charge.util.enums.*;
import com.kehutong.common.DeptService;
import com.kehutong.common.DoveClient;
import com.kehutong.common.IpUtils;
import com.kehutong.common.TokenService;
import com.kehutong.common.dto.DeptDTO;
import com.kehutong.common.util.BigDecimalUtils;
import com.kehutong.common.util.Token;
import org.coraframework.converter.util.StringUtil;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.connection.ThreadLocalCache;
import org.coraframework.orm.jdbc.execute.entity.FindArray;
import org.coraframework.util.Objects;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 账单接口 （小程序/企微 ）
 * @Author jian Ye
 * 2021-08-05
 */
@MvcAction
@ReqMapping("/kht-bin/charges/bill")
public class ChargeBillAction {

    static final Logger logger = LoggerFactory.getLogger(ChargeBillAction.class);


    @Inject
    DeptService deptService;
    @Inject
    private TokenService tokenService;
    @Inject
    private JdbcSession jdbcSession;
    @Inject
    CommonClient commonClient;
    @Inject
    DoveClient doveClient;
    @Inject
    ChargeBillInterimService chargeBillInterimService;
    @Inject
    ChargeBillItemsService chargeBillItemsService;
    @Inject
    ChargeBillHouseService chargeBillHouseService;
    @Inject
    ChargeTypeService chargeTypeService;
    @Inject
    ChargeTypeTempService chargeTypeTempService;
    @Inject
    ChargeReFundService chargeReFundService;
    @Inject
    ThirdPayManageService thirdPayManageService;
    @Inject
    ChargeOrderService chargeOrderService;
    @Inject
    ChargeOrderItemService chargeOrderItemService;
    @Inject
    CommonService commonService;



    /**
     * 【收账管理】 - （未收）--企微
     * 搜索条件：小区、业主、收费类型、账单时间，已收、未收
     */
    @ReqMapping("/findBillManage")
    public Object findBillManage(JSONObject jsonObject, Token token) throws Exception {
        //1未收，2已收
        String nums = jsonObject.getString("billStatus");
        if(nums.equals(ChargeBillStatusEnum.BILL_WAIT_PAID.getId())){
            return chargeBillItemsService.findBillManage(jsonObject, token);
        }else{
            jsonObject.put("orderStatus","3");
            jsonObject.put("token",token);
            jsonObject.put("orderYearMonth",jsonObject.getString("readYearMonth"));

           return chargeOrderItemService.findOrderItemList(jsonObject,token);
        }
    }


    /**
     * 【账单管理】 - 常规收费类型下拉框
     */
    @ReqMapping("/findFeeTypeData")
    public Object findFeeTypeData(JSONObject jsonObject, Token token) {

        return chargeTypeService.findList(jsonObject);
    }

    /**
     * 【临时账单管理】 - 临时收费类型下拉
     */
    @Bean(newInstance=true, copy=true)
    @ReqMapping("/feeTypeDown")
    public Object feeTypeDown(JSONObject jsonObject,Token token) throws Exception {

        return chargeTypeTempService.findList(jsonObject);
    }


    /**
     * 【收账详情】 - 列表以及下拉數據
     * 搜索条件：type: 1、按周期或 2、按收费项统计
     */
    @ReqMapping("/findBillDetail")
    public Object findBillDetail(JSONObject jsonObject, Token token) {

        jsonObject.put("billStatus", ChargeBillStatusEnum.BILL_WAIT_PAID.getId());

        List<ChargeBillItemAppDTO> billItemAppDTOS = chargeBillItemsService.findBillUser(jsonObject, token);

        for (int i = 0; i < billItemAppDTOS.size(); i++) {
            ChargeBillItemAppDTO sto = billItemAppDTOS.get(i);
            String billYearMonth = sto.getBillYearMonth();
            jsonObject.put("billYearMonth",billYearMonth);
            List<ChargeBillItems> billDown =  jdbcSession.findArray(ChargeBillItems.class)
                    .eq("deleted", false)
                    .eq(jsonObject,"userNo")
                    .eq(jsonObject,"houseNo")
                    .eq(jsonObject, "feeTypeNo")
                    .eq("billStatus", ChargeBillStatusEnum.BILL_WAIT_PAID.getId())
                    .eq(jsonObject,"houseBillNo")
                    .like(jsonObject,"billYearMonth")
                    .exe();

            //已包含违约金了
            BigDecimal unPayTotal = billDown.stream().map(b -> b.getPayableAmount() == null ? BigDecimal.ZERO : b.getPayableAmount()).reduce(BigDecimal::add).get();
            //BigDecimal penaltyTotal = billDown.stream().map(b -> b.getPayableAmount() == null ? BigDecimal.ZERO : b.getPenaltyAmount()).reduce(BigDecimal::add).get();
            sto.setUnPayAmount(unPayTotal);
            sto.setBillItems(billDown);
        }

        return billItemAppDTOS;
    }


    /**
     * 【企微收账详情】 - 列表以及下拉數據
     * 搜索条件：type: 1、按周期或 2、按收费项统计
     */
    @ReqMapping("/getBillDetail")
    public Object getBillDetail(JSONObject jsonObject) {

        jsonObject.put("billStatus", ChargeBillStatusEnum.BILL_WAIT_PAID.getId());
        List<ChargeBillItems> items = jdbcSession.findArray(ChargeBillItems.class)
                .eq(jsonObject, "userNo", "houseNo", "billStatus")
                .noEq("billStatus", ChargeBillStatusEnum.BILL_PAID_CLOSE.getId())
                .exe();
        String type = jsonObject.getString("type");
        if (type.equals("1")) {
            return getYeadMonth(items);
        } else {
            return getFeeType( items);
        }
    }


    private List<JSONObject> getFeeType(List<ChargeBillItems> items) {

        Map<String, Map<String, List<ChargeBillItems>>> details = new HashMap<>();

        for (ChargeBillItems temp : items) {
            String feeTypeNo = temp.getFeeTypeNo() + "-" + temp.getFeeTypeName();
            Map<String, List<ChargeBillItems>> yearMonthMap = details.get(feeTypeNo);
            if (Objects.isNull(yearMonthMap)) {
                yearMonthMap = new HashMap<>();
            }
            String yearMonth = temp.getBillYearMonth();
            List<ChargeBillItems> billItems = yearMonthMap.get(yearMonth);
            if (Objects.isEmpty(billItems)) {
                billItems = new ArrayList<>();
            }
            billItems.add(temp);
            yearMonthMap.put(yearMonth, billItems);
            details.put(feeTypeNo, yearMonthMap);
        }

        List<JSONObject> result = new ArrayList<>();
        for (String key : details.keySet()){
            String[] keys = key.split("-");
            String no = keys[0];
            String name = keys[1];
            Map<String, List<ChargeBillItems>> maps = details.get(key);

            JSONObject json = new JSONObject();
            json.put("feeTypeName", name);
            json.put("feeTypeNo", no);
            BigDecimal totalAmount = BigDecimal.ZERO;
            List<JSONObject> list = new ArrayList<>();
            for (String mapKey: maps.keySet()){
                BigDecimal payableAmount = BigDecimal.ZERO;
                List<ChargeBillItems> temps = maps.get(mapKey);
                for (ChargeBillItems temp : temps) {
                    payableAmount = BigDecimalUtils.add(payableAmount, temp.getPayableAmount(), 2);
                }
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("yearMonth", mapKey);
                jsonObject.put("amount", payableAmount);
                jsonObject.put("list", temps);
                list.add(jsonObject);
                totalAmount = BigDecimalUtils.add(totalAmount, payableAmount, 2);
            }

            if (list.size() > 0) {
                Collections.sort(list, new Comparator<JSONObject>() {
                    @Override
                    public int compare(JSONObject m1, JSONObject m2) {
                        String m1Key = m1.getString("yearMonth");
                        String m2Key = m2.getString("yearMonth");
                        return m2Key.compareTo(m1Key);
                    }
                });
            }

            json.put("amount", totalAmount);
            json.put("list", list);
            result.add(json);
        }

        return result;
    }

    private List<JSONObject> getYeadMonth(List<ChargeBillItems> items) {
        Map<String, List<ChargeBillItems>> maps = new HashMap<>();
        for (ChargeBillItems temp : items) {
            String yearMonth = temp.getBillYearMonth();
            List<ChargeBillItems> list = maps.get(yearMonth);
            if (Objects.isEmpty(list)) {
                list = new ArrayList<>();
            }
            list.add(temp);
            maps.put(yearMonth, list);
        }

        List<JSONObject> result = new ArrayList<>();
        for (String key : maps.keySet()) {

            BigDecimal payableAmount = BigDecimal.ZERO;
            List<ChargeBillItems> temps = maps.get(key);
            for (ChargeBillItems temp : temps) {
                payableAmount = payableAmount.add(temp.getPayableAmount());
            }
            JSONObject json = new JSONObject();
            json.put("amount", payableAmount);
            json.put("yearMonth", key);
            json.put("list", maps.get(key));
            result.add(json);
        }
        Collections.sort(result, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject m1, JSONObject m2) {
                String m1Key = m1.getString("yearMonth");
                String m2Key = m2.getString("yearMonth");
                return m2Key.compareTo(m1Key);
            }
        });
        return result;
    }

    /**
     * 【收账详情】 - 点击下拉的数据
     * 搜索条件：type: 1、按周期或 2、按收费项统计
     */
    @ReqMapping("/findBillDown")
    public Object findBillDown(JSONObject jsonObject, Token token){

        return chargeBillItemsService.findBillDown(jsonObject,token);
    }


    /**
     * 小程序---（按月付款接口）
     * @param jsonObject
     * @param request
     * @return
     * @throws Exception
     */
    @ReqMapping("/billYearMonthPay")
    public Object billYearMonthPay (JSONObject jsonObject, HttpServletRequest request) throws Exception {
        Token token = tokenService.getUserToken(request);
        if (!checkLogin(token)) {
            return Result.error(0, "请先登录");
        }

        token.setCompanyNo(request.getHeader("companyNo"));

        String appId = jsonObject.getString("appId");
        if (Objects.isEmpty(appId)) {
            return Result.error(0, "appId不能为空.");
        }

        //生成订单号
        String batchOrderNo = CommonUtil.generateRandom("BT");
        // 生成订单号
        String orderNo = CommonUtil.generateRandom("DD");

        List<ChargeBillItems> itemBillNoList = jdbcSession.findArray(ChargeBillItems.class)
                .eq("deleted", false)
                .eq(jsonObject,"communityNo","billYearMonth","houseNo")
                .eq("billStatus", ChargeBillStatusEnum.BILL_WAIT_PAID.getId())
                .exe();

        String houseBillNo = null;
        String communityNo = jsonObject.getString("communityNo");

        //2、创建子订单
        for (int i = 0; i < itemBillNoList.size(); i++) {
            ChargeBillItems itemBill = itemBillNoList.get(i);
            ChargeOrderItem orderItem = Pool.newInstance(ChargeOrderItem.class);
            orderItem.setOrderNo(orderNo);
            String orderItemNo = CommonUtil.generateRandom("DD");
            orderItem.setOrderItemNo(orderItemNo);
            orderItem.setBuildNo(itemBill.getBuildNo());
            orderItem.setUserNo(token.getUuid());
            orderItem.setChargeName(token.getUsername());
            orderItem.setOrderStatus(ChargeOrderStatusEnum.ORDER_WAIT_PAY);
            orderItem.setHouseBillNo(itemBill.getHouseBillNo());
            orderItem.setCommunityNo(communityNo);
            orderItem.setItemBillNo(itemBill.getItemBillNo());
            orderItem.setBillAddress(itemBill.getBillAddress());
            orderItem.setPayMethod(CommonEnum.COM_PAY_NOT);

            houseBillNo = itemBill.getHouseBillNo();

            jdbcSession.insert(orderItem);
        }

        //创建管理订单
        ChargeOrderManage orderManage = Pool.newInstance(ChargeOrderManage.class);
        orderManage.setOrderNo(orderNo);
        orderManage.setCreateName(token.getUsername());
        orderManage.setUserNo(token.getUuid());
        orderManage.setChargeName(token.getUsername());
        orderManage.setOrderStatus(ChargeOrderStatusEnum.ORDER_WAIT_PAY);
        orderManage.setOptStatus(ChargeOrderStatusEnum.ORDER_REFUND_NOT);
        orderManage.setHouseBillNo(houseBillNo);
        orderManage.setCommunityNo(communityNo);
        orderManage.setHouseNo(jsonObject.getString("houseNo"));
        orderManage.setBatchOrderNo(batchOrderNo);
        orderManage.setPayMethod(CommonEnum.COM_PAY_NOT);

        jdbcSession.insert(orderManage);

        commonService.insetLogger(orderManage.getOrderNo(),
                ChargeLogEnum.LOG_CHARGE_ORDER_COM.getDesc(),
                "添加订单数据",
                ChargeOrderStatusEnum.ORDER_WAIT_PAY.getDesc(),
                ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(), "添加订单", token.getUsername());

        JSONObject rs = doveClient.post("/kht-bin/wechat/getMemberMap", http -> {
            http.addParam("khtId",token.getUuid());
            http.addParam("mn_app_id",appId);
        });

        int code = rs.getIntValue("code");
        if (code != 200) {
            return Result.error(code, rs.getString("message"));
        }
        JSONObject memberMap = rs.getJSONObject("data");
        if(Objects.isEmpty(memberMap)){
            return Result.error(1,"当前用户没有绑定OpenId.");
        }

        //调用支付接口
        ChargePayManage cpm = Pool.newInstance(ChargePayManage.class);
        cpm.setCreateIp(IpUtils.getAddr(request));
        cpm.setCreateName(token.getUsername());
        cpm.setOrderNo(batchOrderNo);
        cpm.setCompanyNo(token.getCompanyNo());
        cpm.setCommunityNo(communityNo);
        cpm.setCompanyName(token.getCompanyName());
        cpm.setOpenId(memberMap.getString("mn_open_id"));
        cpm.setOrderOrigin(CommonEnum.COM_PAY_ROUTINE);
        cpm.setPayMethod(CommonEnum.COM_PAY_WXPAY_MP);

        return thirdPayManageService.callPayOrder(cpm, jsonObject,token);
    }

    /**
     * 付款接口-(企微端-常规-类目-临时)
     * @param jsonObject
     * @param request
     * @return
     * @throws Exception
     */
    @ReqMapping("/appBillPay")
    public Object appBillPay(Token token, JSONObject jsonObject, HttpServletRequest request) throws Exception {
        /**
         * {
         *  "communityNo": "",
         *  "orderOrigin": "ROUTINE",
         *  "houseNo": "",
         *  "list": ["12321312","123123"]
         * }
         */
        // orderOrigin: 常规: ROUTINE，临时：INTERIM
       if(jsonObject.getString("orderOrigin").equals("ROUTINE")){
           return submitItemPay(token,jsonObject,request);
       }else if(jsonObject.getString("orderOrigin").equals("INTERIM")){
           return submitInterimPay(token,jsonObject,request);
       }else{
           return Result.error(1232,"支付来源不正确！");
       }
    }

    /**
     * 常规支付--企微
     * @param token
     * @param jsonObject
     * @param request
     * @return
     * @throws Exception
     */
    private Object submitItemPay(Token token, JSONObject jsonObject, HttpServletRequest request) throws Exception {

        String communityNo = jsonObject.getString("communityNo");


        List<String> list = JSONObject.parseArray(jsonObject.getJSONArray("list").toJSONString(), String.class);

        JSONArray array = jsonObject.getJSONArray("list");

        jsonObject.put("itemBillNo",array);

        List<ChargeBillItems> itemBillNoList = jdbcSession.findArray(ChargeBillItems.class)
                .eq("deleted", false)
                .in(jsonObject, "itemBillNo")
                .exe();

        //生成订单号
        String batchOrderNo = CommonUtil.generateRandom("BT");

        //重新组装数据
        Map<String,List<ChargeBillItems>> maps = new LinkedHashMap<>();
        for (ChargeBillItems temp : itemBillNoList) {
            String yearMonth = temp.getBillYearMonth() + "," + temp.getHouseBillNo();
            List<ChargeBillItems> lists = maps.get(yearMonth);
            if (Objects.isEmpty(lists)) {
                lists = new ArrayList<>();
            }
            lists.add(temp);
            maps.put(yearMonth, lists);
        }

        for (String key : maps.keySet()) {
            String[] keys = key.split(",");

            //生成订单号
            String orderNo = CommonUtil.generateRandom("DD");

            String houseBillNo = keys[1];
            //1、创建管理订单
            ChargeOrderManage orderManage = Pool.newInstance(ChargeOrderManage.class);
            orderManage.setOrderNo(orderNo);
            orderManage.setCreateName(token.getUsername());
            orderManage.setOrderStatus(ChargeOrderStatusEnum.ORDER_WAIT_PAY);
            orderManage.setOptStatus(ChargeOrderStatusEnum.ORDER_REFUND_NOT);
            orderManage.setHouseBillNo(houseBillNo);
            orderManage.setCommunityNo(communityNo);
            orderManage.setOrderYearMonth(keys[0]);
            orderManage.setNegotiateAmount(BigDecimal.ZERO);
            orderManage.setCreateName(token.getUsername());
            orderManage.setOrderOrigin(CommonEnum.COM_PAY_ROUTINE);
            orderManage.setBatchOrderNo(batchOrderNo);
            orderManage.setOriginFrom(CommonEnum.COM_PAY_WXPAY_QW);
            orderManage.setPayMethod(CommonEnum.COM_PAY_NOT);

            List<ChargeBillItems> lists = maps.get(key);
            BigDecimal amounts = BigDecimal.ZERO;

            for (ChargeBillItems itemBill:lists) {
                ChargeOrderItem orderItem = Pool.newInstance(ChargeOrderItem.class);
                orderItem.setOrderNo(orderNo);
                String orderItemNo = CommonUtil.generateRandom("DD");
                orderItem.setOrderItemNo(orderItemNo);
                orderItem.setOrderStatus(ChargeOrderStatusEnum.ORDER_WAIT_PAY);
                orderItem.setHouseBillNo(houseBillNo);
                orderItem.setCommunityNo(communityNo);
                orderItem.setHouseNo(itemBill.getHouseNo());
                orderItem.setBuildNo(itemBill.getBuildNo());
                orderItem.setBillAddress(itemBill.getBillAddress());
                orderItem.setFeeTypeNo(itemBill.getFeeTypeNo());
                orderItem.setFeeTypeName(itemBill.getFeeTypeName());
                orderItem.setUsageNumber(itemBill.getUsageNumber());
                orderItem.setCalcUnit(itemBill.getCalcUnit());
                orderItem.setOrderYearMonth(keys[0]);
                orderItem.setCommunityName(itemBill.getCommunityName());
                orderItem.setItemBillNo(itemBill.getItemBillNo());
                orderItem.setOrderAmount(itemBill.getPayableAmount());
                orderItem.setPayableAmount(itemBill.getPayableAmount());
                orderItem.setDepartmentName(itemBill.getDepartmentName());
                orderItem.setDepartmentNo(itemBill.getDepartmentNo());
                orderItem.setDepartmentNos(itemBill.getDepartmentNos());
                orderItem.setCreateName(token.getUsername());
                orderItem.setChargeName(itemBill.getChargeName());
                orderItem.setUserNo(itemBill.getUserNo());
                orderItem.setResidentsType(itemBill.getResidentsType());
                orderItem.setOrderOrigin(CommonEnum.COM_PAY_ROUTINE);
                orderItem.setPayMethod(CommonEnum.COM_PAY_NOT);
                jdbcSession.insert(orderItem);

                amounts = amounts.add(itemBill.getPayableAmount());
                orderManage.setCommunityName(itemBill.getCommunityName());
                orderManage.setBillAddress(itemBill.getBillAddress());
                orderManage.setCommunityBillNo(itemBill.getCommunityBillNo());
                orderManage.setDepartmentName(itemBill.getDepartmentName());
                orderManage.setDepartmentNo(itemBill.getDepartmentNo());
                orderManage.setDepartmentNos(itemBill.getDepartmentNos());
                orderManage.setChargeName(itemBill.getChargeName());
                orderManage.setUserNo(itemBill.getUserNo());
                orderManage.setHouseNo(itemBill.getHouseNo());
                orderManage.setResidentsType(itemBill.getResidentsType());
            }

            orderManage.setBillAmount(amounts);
            orderManage.setOrderAmount(amounts);
            orderManage.setPayableAmount(amounts);
            jdbcSession.insert(orderManage);

            commonService.insetLogger(orderManage.getOrderNo(),
                    ChargeLogEnum.LOG_CHARGE_ORDER_COM.getDesc(),
                    "添加订单数据",
                    ChargeOrderStatusEnum.ORDER_WAIT_PAY.getDesc(),
                    ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(), "添加订单", token.getUsername());
        }

        //调用支付接口
        ChargePayManage cpm = Pool.newInstance(ChargePayManage.class);
        cpm.setCreateIp(IpUtils.getAddr(request));
        cpm.setCreateName(token.getUsername());
        cpm.setOrderNo(batchOrderNo);
        cpm.setCompanyNo(token.getCompanyNo());
        cpm.setCommunityNo(communityNo);
        cpm.setCompanyName(token.getCompanyName());
        cpm.setOrderOrigin(CommonEnum.COM_PAY_ROUTINE);
        cpm.setPayMethod(CommonEnum.COM_PAY_WXPAY_WEB);
        return thirdPayManageService.callPayOrder(cpm, jsonObject,token);
    }

    /**
     * 企微--临时支付
     * @return
     */
    private Object submitInterimPay(Token token, JSONObject jsonObject, HttpServletRequest request) throws Exception {

        /**
         * {
         *     "communityNo":"162787448189010009",
         *     "houseNo":"163012141849010004",
         *     "list":["12312312321312312"],
         *     "originType":"INTERIM"
         * }
         */

        //List<String> list = JSONObject.parseArray(jsonObject.getJSONArray("list").toJSONString(), String.class);

        JSONArray array = jsonObject.getJSONArray("list");
        jsonObject.put("interimBillNo",array);
        ChargeBillInterim entity = jdbcSession.findOne(ChargeBillInterim.class).in(jsonObject,"interimBillNo").exe();

        List<ChargeOrderInterim> interims = jdbcSession.findArray(ChargeOrderInterim.class)
                .eq("interimBillNo",entity.getInterimBillNo())
                .eq("orderStatus",ChargeOrderStatusEnum.ORDER_WAIT_PAY).exe();

        String orderNo = null;

        if(Objects.isEmpty(interims)){

            ChargeBillInterim billInterim = jdbcSession.findOne(ChargeBillInterim.class)
                    .eq("interimBillNo",entity.getInterimBillNo()).exe();
            // 创建临时账单
            ChargeOrderInterim interim = Pool.newInstance(ChargeOrderInterim.class);
            interim.setOrderStatus(ChargeOrderStatusEnum.ORDER_WAIT_PAY);
            interim.setOptStatus(ChargeOrderStatusEnum.ORDER_REFUND_NOT);
            interim.setOrderOrigin(CommonEnum.COM_PAY_INTERIM);
            orderNo = CommonUtil.generateRandom("DS");
            interim.setInterimOrderNo(orderNo);
            interim.setCommunityNo(entity.getCommunityNo());
            interim.setBillAmount(entity.getBillAmount());
            interim.setPayableAmount(entity.getBillAmount());
            interim.setChargeName(entity.getChargeName());
            interim.setCreateName(token.getUsername());
            interim.setOrderAmount(entity.getBillAmount());
            interim.setInterimBillNo(entity.getInterimBillNo());
            interim.setOriginFrom(CommonEnum.COM_PAY_WXPAY_QW);
            interim.setCommunityName(billInterim.getCommunityName());
            interim.setFeeTypeNo(billInterim.getFeeTypeNo());
            interim.setFeeTypeName(billInterim.getFeeTypeName());
            interim.setUserNo(billInterim.getUserNo());
            interim.setBillAddress(billInterim.getBillAddress());
            interim.setOrderYearMonth(billInterim.getBillYearMonth());
            interim.setPayMethod(CommonEnum.COM_PAY_NOT);

            jdbcSession.insert(interim);

            commonService.insetLogger(interim.getInterimOrderNo(),
                    ChargeLogEnum.LOG_CHARGE_ORDER_INT.getDesc(),
                    "临时订单功能",
                    ChargeOrderStatusEnum.ORDER_WAIT_PAY.getDesc(),
                    ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(), "添加临时订单", token.getUsername());
        }else{
            orderNo = interims.get(0).getInterimOrderNo();
        }

        //调用支付接口
        ChargePayManage cpm = Pool.newInstance(ChargePayManage.class);
        cpm.setCreateIp(IpUtils.getAddr(request));
        cpm.setCreateName(token.getUsername());
        cpm.setOrderNo(orderNo);
        cpm.setCompanyNo(token.getCompanyNo());
        cpm.setCommunityNo(entity.getCommunityNo());
        cpm.setCompanyName(token.getCompanyName());
        cpm.setOrderOrigin(CommonEnum.COM_PAY_INTERIM);
        cpm.setPayMethod(CommonEnum.COM_PAY_WXPAY_WEB);
        return thirdPayManageService.callPayOrder(cpm, jsonObject,token);
    }



    /**
     * 付款接口-(小程序-常规-类目)
     * @param jsonObject
     * @param request
     * @return
     * @throws Exception
     */
    @ReqMapping("/billPay")
    public Object billPay(JSONObject jsonObject, HttpServletRequest request) throws Exception {

        Token token = tokenService.getUserToken(request);
        if (!checkLogin(token)) {
            return Result.error(0, "请先登录");
        }

        token.setCompanyNo(request.getHeader("companyNo"));

        String appId = jsonObject.getString("appId");
        if (Objects.isEmpty(appId)) {
            return Result.error(0, "appId不能为空.");
        }

        //生成订单号
        String batchOrderNo = CommonUtil.generateRandom("BT");
        String communityNo = jsonObject.getString("communityNo");

        List<JSONObject> list = JSONObject.parseArray(jsonObject.getJSONArray("list").toJSONString(), JSONObject.class);
        list.forEach(obj ->{
            String houseBillNo = obj.getString("houseBillNo");
            //生成订单号
            String orderNo = CommonUtil.generateRandom("DD");

            //1、创建管理订单
            ChargeOrderManage orderManage = Pool.newInstance(ChargeOrderManage.class);
            orderManage.setOrderNo(orderNo);
            orderManage.setCreateName(token.getUsername());
            orderManage.setUserNo(token.getUuid());
            orderManage.setChargeName(token.getUsername());
            orderManage.setOrderStatus(ChargeOrderStatusEnum.ORDER_WAIT_PAY);
            orderManage.setOptStatus(ChargeOrderStatusEnum.ORDER_REFUND_NOT);
            orderManage.setHouseBillNo(houseBillNo);
            orderManage.setCommunityNo(communityNo);
            orderManage.setBatchOrderNo(batchOrderNo);
            orderManage.setHouseNo(jsonObject.getString("houseNo"));
            orderManage.setNegotiateAmount(BigDecimal.ZERO);
            orderManage.setOrderOrigin(CommonEnum.COM_PAY_ROUTINE);
            orderManage.setOriginFrom(CommonEnum.COM_PAY_WXPAY_MP);
            orderManage.setPayMethod(CommonEnum.COM_PAY_NOT);

            BigDecimal amounts = BigDecimal.ZERO;

            List<ChargeBillItems> itemBillNoList = jdbcSession.findArray(ChargeBillItems.class)
                    .eq("deleted", false)
                    .in("itemBillNo",obj.getJSONArray("itemBillNo"))
                    .eq(jsonObject,"houseNo")
                    .exe();
            //2、创建子订单
            for (int i = 0; i < itemBillNoList.size(); i++) {
                ChargeBillItems itemBill = itemBillNoList.get(i);
                ChargeOrderItem orderItem = Pool.newInstance(ChargeOrderItem.class);
                orderItem.setOrderNo(orderNo);
                String orderItemNo = CommonUtil.generateRandom("DD");
                orderItem.setOrderItemNo(orderItemNo);
                orderItem.setUserNo(token.getUuid());
                orderItem.setChargeName(token.getUsername());
                orderItem.setOrderStatus(ChargeOrderStatusEnum.ORDER_WAIT_PAY);
                orderItem.setHouseBillNo(houseBillNo);
                orderItem.setBuildNo(itemBill.getBuildNo());
                orderItem.setCommunityNo(communityNo);
                orderItem.setItemBillNo(itemBill.getItemBillNo());
                orderItem.setHouseNo(itemBill.getHouseNo());
                orderItem.setBillAddress(itemBill.getBillAddress());
                orderItem.setFeeTypeNo(itemBill.getFeeTypeNo());
                orderItem.setFeeTypeName(itemBill.getFeeTypeName());
                orderItem.setUsageNumber(itemBill.getUsageNumber());
                orderItem.setCalcUnit(itemBill.getCalcUnit());
                orderItem.setOrderYearMonth(itemBill.getBillYearMonth());
                orderItem.setCommunityName(itemBill.getCommunityName());
                orderItem.setOrderAmount(itemBill.getPayableAmount());
                orderItem.setPayableAmount(itemBill.getPayableAmount());
                orderItem.setDepartmentName(itemBill.getDepartmentName());
                orderItem.setDepartmentNo(itemBill.getDepartmentNo());
                orderItem.setDepartmentNos(itemBill.getDepartmentNos());
                orderItem.setCreateName(token.getUsername());
                orderItem.setResidentsType(itemBill.getResidentsType());
                orderItem.setOrderOrigin(CommonEnum.COM_PAY_ROUTINE);
                orderItem.setPayMethod(CommonEnum.COM_PAY_NOT);
                jdbcSession.insert(orderItem);

                amounts = amounts.add(itemBill.getPayableAmount());
                orderManage.setCommunityName(itemBill.getCommunityName());
                orderManage.setBillAddress(itemBill.getBillAddress());
                orderManage.setCommunityBillNo(itemBill.getCommunityBillNo());
                orderManage.setDepartmentName(itemBill.getDepartmentName());
                orderManage.setDepartmentNo(itemBill.getDepartmentNo());
                orderManage.setDepartmentNos(itemBill.getDepartmentNos());
                orderManage.setChargeName(itemBill.getChargeName());
                orderManage.setUserNo(itemBill.getUserNo());
                orderManage.setHouseNo(itemBill.getHouseNo());
                orderManage.setResidentsType(itemBill.getResidentsType());
                orderManage.setOrderYearMonth(itemBill.getBillYearMonth());
            }

            orderManage.setBillAmount(amounts);
            orderManage.setOrderAmount(amounts);
            orderManage.setPayableAmount(amounts);
            jdbcSession.insert(orderManage);

            commonService.insetLogger(orderManage.getOrderNo(),
                    ChargeLogEnum.LOG_CHARGE_ORDER_COM.getDesc(),
                    "添加订单数据",
                    ChargeOrderStatusEnum.ORDER_WAIT_PAY.getDesc(),
                    ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(), "添加订单", token.getUsername());
        });

        JSONObject rs = doveClient.post("/kht-bin/wechat/getMemberMap", http -> {
            http.addParam("khtId",token.getUuid());
            http.addParam("mn_app_id",appId);
        });
        int code = rs.getIntValue("code");
        if (code != 200) {
            return Result.error(code, rs.getString("message"));
        }
        JSONObject memberMap = rs.getJSONObject("data");
        if(Objects.isEmpty(memberMap)){
            return Result.error(1,"当前用户没有绑定OpenId.");
        }

        //调用支付接口
        ChargePayManage cpm = Pool.newInstance(ChargePayManage.class);
        cpm.setCreateIp(IpUtils.getAddr(request));
        cpm.setCreateName(token.getUsername());
        cpm.setOrderNo(batchOrderNo);
        cpm.setCompanyNo(token.getCompanyNo());
        cpm.setCommunityNo(communityNo);
        cpm.setCompanyName(token.getCompanyName());
        cpm.setOpenId(memberMap.getString("mn_open_id"));
        cpm.setOrderOrigin(CommonEnum.COM_PAY_ROUTINE);
        cpm.setPayMethod(CommonEnum.COM_PAY_WXPAY_MP);
        return thirdPayManageService.callPayOrder(cpm, jsonObject,token);
    }

    /**
     * 临时账单作废(单条或多条)
     * @param jsonObject
     * @return
     */
    @ReqMapping("/cancelInterimApp")
    public Object cancelInterimBill(JSONObject jsonObject, Token token) {

        return chargeBillInterimService.cancelInterimBill(jsonObject,token);
    }

    /**
     * 小程序-（临时支付）
     * @param jsonObject
     * @param request
     * @return
     * @throws Exception
     */
    @ReqMapping("/billInterimPay")
    public Object billInterimPay(JSONObject jsonObject, HttpServletRequest request) throws Exception {
        Token token = tokenService.getUserToken(request);
        if (!checkLogin(token)) {
            return Result.error(0, "请先登录");
        }

        token.setCompanyNo(request.getHeader("companyNo"));

        String appId = jsonObject.getString("appId");
        if (Objects.isEmpty(appId)) {
            return Result.error(0, "appId不能为空.");
        }

        ChargeBillInterim entity = Pool.get(ChargeBillInterim.class, jsonObject.getString("id"));

        List<ChargeOrderInterim> interims = jdbcSession.findArray(ChargeOrderInterim.class)
                .eq("interimBillNo",entity.getInterimBillNo())
                .eq("orderStatus",ChargeOrderStatusEnum.ORDER_WAIT_PAY).exe();

        String orderNo = null;

        if(Objects.isEmpty(interims)){

            ChargeBillInterim billInterim = jdbcSession.findOne(ChargeBillInterim.class)
                    .eq("interimBillNo",entity.getInterimBillNo()).exe();
            // 创建临时账单
            ChargeOrderInterim interim = Pool.newInstance(ChargeOrderInterim.class);
            interim.setOrderStatus(ChargeOrderStatusEnum.ORDER_WAIT_PAY);
            interim.setOptStatus(ChargeOrderStatusEnum.ORDER_REFUND_NOT);
            interim.setOrderOrigin(CommonEnum.COM_PAY_INTERIM);
            orderNo = CommonUtil.generateRandom("DS");
            interim.setInterimOrderNo(orderNo);
            interim.setCommunityNo(entity.getCommunityNo());
            interim.setBillAmount(entity.getBillAmount());
            interim.setChargeName(entity.getChargeName());
            interim.setCreateName(token.getUsername());
            interim.setOrderAmount(entity.getBillAmount());
            interim.setPayableAmount(entity.getBillAmount());
            interim.setInterimBillNo(entity.getInterimBillNo());
            interim.setBillAddress(entity.getBillAddress());
            interim.setOriginFrom(CommonEnum.COM_PAY_WXPAY_MP);
            interim.setPayMethod(CommonEnum.COM_PAY_NOT);
            interim.setCommunityName(entity.getCommunityName());
            interim.setFeeTypeNo(entity.getFeeTypeNo());
            interim.setFeeTypeName(entity.getFeeTypeName());
            interim.setUserNo(entity.getUserNo());
            interim.setOrderYearMonth(entity.getBillYearMonth());

            jdbcSession.insert(interim);

            commonService.insetLogger(interim.getInterimOrderNo(),
                    ChargeLogEnum.LOG_CHARGE_ORDER_INT.getDesc(),
                    "临时订单功能",
                    ChargeOrderStatusEnum.ORDER_WAIT_PAY.getDesc(),
                    ChargeOrderStatusEnum.ORDER_REFUND_NOT.getDesc(), "添加临时订单", token.getUsername());
        }else{
            orderNo = interims.get(0).getInterimOrderNo();
        }


        JSONObject rs = doveClient.post("/kht-bin/wechat/getMemberMap", http -> {
            http.addParam("khtId",token.getUuid());
            http.addParam("mn_app_id",appId);
        });
        int code = rs.getIntValue("code");
        if (code != 200) {
            return Result.error(code, rs.getString("message"));
        }
        JSONObject memberMap = rs.getJSONObject("data");
        if(Objects.isEmpty(memberMap)){
            return Result.error(1,"当前用户没有绑定OpenId.");
        }
        // 创建支付信息
        ChargePayManage cpm = Pool.newInstance(ChargePayManage.class);
        cpm.setCreateIp(IpUtils.getAddr(request));
        cpm.setCreateName(token.getUsername());
        cpm.setOrderNo(orderNo);
        cpm.setCompanyNo(token.getCompanyNo());
        cpm.setCommunityNo(entity.getCommunityNo());
        cpm.setCompanyName(token.getCompanyName());
        cpm.setOpenId(memberMap.getString("mn_open_id"));
        cpm.setOrderOrigin(CommonEnum.COM_PAY_INTERIM);
        cpm.setPayMethod(CommonEnum.COM_PAY_WXPAY_MP);
        return thirdPayManageService.callPayOrder(cpm, jsonObject,token);
    }

    /**
     * 【企微端】新增临时收费账单
     */
    @Bean(newInstance=true, copy=true)
    @ReqMapping("/addBillInterim")
    public Object addBillInterim(ChargeBillInterim entity,Token token) throws Exception {

        entity.setCreateName(token.getUsername());
        String billNo = CommonUtil.generateRandom("LS");
        entity.setInterimBillNo(billNo);
        entity.setBillAddress(entity.getCommunityName());

        chargeBillInterimService.save(entity);
        //返回添加的id
        return Result.success(billNo);
    }

    /**
     * 查询所有库的临时收费类型
     * @return
     */
    @ReqMapping("/feeTypeAllDown")
    public Object findFeeTypeAll(JSONObject jsonObject,Token token){
        logger.info("【小程序】根据年月查询账单详情列表参数:{}",jsonObject);
        //跨库请求数据
        JSONArray result = new JSONArray();
        JSONArray khtIds = jsonObject.getJSONArray("khtIds");
        jsonObject.remove("token");

        List<ChargeTypeTemp> feeTypeAll = new LinkedList<>();

        if (Objects.nonEmpty(khtIds)) {
            for (Object khtId : khtIds) {
                String companyNo = (String) khtId;
                //切换公司
                ThreadLocalCache.current().setCorpId(companyNo);

                try{
                    List<ChargeTypeTemp> feeTypeList = chargeTypeTempService.findList(jsonObject);
                    feeTypeAll.addAll(feeTypeList);
                }catch (Exception e){

                }
            }
        }

        return feeTypeAll;
    }


    /**
     * 临时收费总列表接口（1未缴和2已缴3作废）
     */
    @ReqMapping("/findBillInterimAll")
    public Object findBillInterimAll(JSONObject jsonObject,HttpServletRequest request) throws Exception {
        Token token = tokenService.getUserToken(request);
        if (!checkLogin(token)) {
            return Result.error(0, "请先登录");
        }
        jsonObject.put("token",token);
        return chargeBillInterimService.findPage(jsonObject);
    }

    /**
     * 临时收费----查看详情
     */
    @ReqMapping("/findBillInterimDetail")
    public Object findBillInterimDetail(JSONObject jsonObject,Token token) throws Exception {

        return Result.success(chargeBillInterimService.getObj(jsonObject));
    }

    /**
     * 临时收费总接口--查询下拉时间
     * @param
     */
    @ReqMapping("/findBillInterimDate")
    public Object findBillInterimDate(JSONObject jsonObject,Token token) throws Exception {

        List<ChargeBillInterim> billInterims = chargeBillInterimService.findList(jsonObject);
        List<String> dateList = new LinkedList<>();
        for (int i = 0; i < billInterims.size(); i++) {
            dateList.add(billInterims.get(i).getBillYearMonth());
        }
        //集合数据去重
        return dateList.stream().distinct().collect(Collectors.toList());
    }


    /**        小程序接口          */

    /**
     * 按年查询数月份据(2021)
     * 参数：房屋编号：houseNo，用户：userNo,年份：year
     */
    @ReqMapping("/findYearData")
    public Object findYearData(JSONObject jsonObject){
        logger.info("【小程序】根据年月查询月账单列表入参:{}",jsonObject);
        Map<String,Object> map = new HashMap<>();
        jsonObject.put("noCloseAndUnPaid", "1");
        List<ChargeBillHouse> houseList = chargeBillHouseService.findList(jsonObject);
        logger.info("【小程序】根据年月查询房屋账单列表返回:{}",houseList);
        Set<String> billYearMonths = houseList.stream().map(h -> h.getBillYearMonth()).collect(Collectors.toSet());

        List<ChargeBillHouse> resultHouseList = new ArrayList<>();
        for (String yearMonth : billYearMonths) {
            ChargeBillHouse chargeBillHouse = Pool.newInstance(ChargeBillHouse.class);
            //本月房屋账单list
            List<ChargeBillHouse> thisMonthList = houseList.stream().filter(h ->
                    h.getBillYearMonth().equals(yearMonth)).collect(Collectors.toList());

            ChargeBillHouse BillHouse = thisMonthList.get(0);
            chargeBillHouse.setBillYearMonth(yearMonth);
            chargeBillHouse.setCommunityNo(BillHouse.getCommunityNo());
            chargeBillHouse.setCommunityName(BillHouse.getCommunityName());
            chargeBillHouse.setHouseNo(BillHouse.getHouseNo());
            chargeBillHouse.setBillAddress(BillHouse.getBillAddress());
            chargeBillHouse.setChargeName(BillHouse.getChargeName());
            chargeBillHouse.setUserNo(BillHouse.getUserNo());
            chargeBillHouse.setBillCycleStart(BillHouse.getBillCycleStart());
            chargeBillHouse.setBillCycleEnd(BillHouse.getBillCycleEnd());
            chargeBillHouse.setBillDate(BillHouse.getBillDate());
            chargeBillHouse.setChargeDate(BillHouse.getChargeDate());
            chargeBillHouse.setPenaltyDate(BillHouse.getPenaltyDate());

            BigDecimal unpayAmount = BigDecimal.ZERO;
            BigDecimal payAmount = BigDecimal.ZERO;
            for (ChargeBillHouse each : thisMonthList) {
                unpayAmount = BigDecimalUtils.add(unpayAmount, BigDecimalUtils.sub(each.getBillAmount(), each.getBillAmountPaid(), 2), 2);
                payAmount = BigDecimalUtils.add(payAmount, each.getBillAmountPaid(), 2);
            }
            chargeBillHouse.setUnPayAmount(unpayAmount);
            chargeBillHouse.setPayAmount(payAmount);

            //月账单总金额
            BigDecimal totalAmount = thisMonthList.stream().map(m ->
                    m.getBillAmount() == null ? BigDecimal.ZERO : m.getBillAmount()).reduce(BigDecimal::add).get();
            chargeBillHouse.setBillAmount(totalAmount);
            //本月未支付房屋订单list --------------------------------------------------------------------------------------
            List<ChargeBillHouse> unPayList = thisMonthList.stream().filter(h ->
                    h.getBillStatus().equals(ChargeBillStatusEnum.BILL_WAIT_PAID)).collect(Collectors.toList());
            logger.info("【小程序】根据年月查询房屋账单待缴费的列表返回unPayList:{}",unPayList);
            //本月已退款房屋订单list --------------------------------------------------------------------------------------
            List<ChargeBillHouse> refundPayList = thisMonthList.stream().filter(h ->
                    h.getChargeStatus().equals(ChargeBillStatusEnum.BILL_REFUND)).collect(Collectors.toList());
            logger.info("【小程序】根据年月查询房屋账单已退款的列表返回refundPayList:{}",refundPayList);

            if(Objects.isEmpty(unPayList) && Objects.isEmpty(refundPayList)){
                //意味着缴费完成
                chargeBillHouse.setUnPayAmount(BigDecimal.ZERO);
                chargeBillHouse.setChargeStatus(ChargeBillStatusEnum.BILL_PAID);
                resultHouseList.add(chargeBillHouse);
                continue;
            }
            //意味着全退款了
            else if(Objects.isEmpty(unPayList) && !Objects.isEmpty(refundPayList)){
                chargeBillHouse.setUnPayAmount(BigDecimal.ZERO);
                chargeBillHouse.setChargeStatus(ChargeBillStatusEnum.BILL_REFUND);
                resultHouseList.add(chargeBillHouse);
                continue;
            }
            //应付款月金额
//            BigDecimal unPayAmount = unPayList.stream().map(h ->
//                    h.getBillAmountUnPaid() == null ? BigDecimal.ZERO : h.getBillAmountUnPaid()).reduce(BigDecimal::add).get();
            //违约金月金额
            BigDecimal penaltyAmount = unPayList.stream().map(h ->
                    h.getPenaltyAmount() == null ? BigDecimal.ZERO : h.getPenaltyAmount()).reduce(BigDecimal::add).get();

//            unPayAmount = BigDecimalUtils.add(unPayAmount,penaltyAmount,2);

            chargeBillHouse.setChargeStatus(ChargeBillStatusEnum.BILL_UN_PAID);
            chargeBillHouse.setHouseBillNo(unPayList.get(0).getHouseBillNo());
            chargeBillHouse.setCommunityBillNo(unPayList.get(0).getCommunityBillNo());
            chargeBillHouse.setPenaltyDate(unPayList.get(0).getPenaltyDate());

            resultHouseList.add(chargeBillHouse);
        }

        /**
        // 查询缴费记录
        List<ChargeOrderManage> orderManages = jdbcSession.findArray(ChargeOrderManage.class)
                .eq("deleted", false)
                .eq(jsonObject, "userNo")
                .eq(jsonObject, "houseNo")
                .like("orderYearMonth", jsonObject.getString("billYearMonth"))
                .markBegin()
                .eq("orderStatus", ChargeOrderStatusEnum.ORDER_PAY_SUCCESS.getId()).or()
                .noEq("optStatus", ChargeOrderStatusEnum.ORDER_REFUND.getId())
                .markEnd()
                .exe();

        BigDecimal payAmount = BigDecimal.ZERO;
        for (ChargeOrderManage each : orderManages) {
            payAmount = BigDecimalUtils.add(payAmount, each.getPaymentAmount(), 2);
        }
        map.put("payAmount",payAmount);*/

        List<ChargeBillItems> billItems = jdbcSession.findArray(ChargeBillItems.class)
                .eq("deleted", false)
                .eq(jsonObject, "houseBillNo")
                .eq(jsonObject, "meterTypeNo")
                .noEq("billStatus", ChargeBillStatusEnum.BILL_PAID_CLOSE.getId())
                .eq(jsonObject, "userNo")
                .eq(jsonObject, "houseNo")
                .like("billYearMonth", jsonObject.getString("billYearMonth"))
                .exe();

        logger.info("【小程序】根据年月查询items账单列表返回:{}",billItems);

        resultHouseList = resultHouseList.stream().sorted(Comparator.comparing(ChargeBillHouse::getBillYearMonth)
                .reversed()).collect(Collectors.toList());

        map.put("houseInfo",resultHouseList);
        map.put("itemSize",billItems.size());

        BigDecimal amount = BigDecimal.ZERO;
        for (ChargeBillItems chargeBillItems : billItems) {
            //BILL_WAIT_PAID
            if(ChargeBillStatusEnum.BILL_WAIT_PAID.equals(chargeBillItems.getBillStatus())){
                amount = BigDecimalUtils.add(amount, chargeBillItems.getPayableAmount(), 2);
            }
        }
        map.put("itemAmount",amount);
        //只查退款成功的数据
        jsonObject.put("applyStatus", ChargeStatusEnum.CS_SUCCESS.getId());
        jsonObject.put("orderYearMonth", jsonObject.getString("billYearMonth"));
        List<ChargeReFundManage> fundManages = chargeReFundService.findList(jsonObject);
        BigDecimal refundAmount = BigDecimal.ZERO;
        for (ChargeReFundManage fundManage : fundManages) {
            refundAmount = refundAmount.add(fundManage.getRefundAmount()==null?BigDecimal.ZERO:fundManage.getRefundAmount());
        }
        map.put("refundAmount",refundAmount);

        logger.info("findYearData:--->itemSize:{},itemAmount:{},refundAmount:{}"
                ,billItems.size(),amount,refundAmount);

        return map;
    }


    /**
     * 账单详情--全部待缴费
     * 参数：
     */
    @ReqMapping("/findBillUnPaid")
    public Object findBillUnPaid(JSONObject jsonObject,Token token) throws Exception {

        return chargeBillItemsService.findBillUser(jsonObject,token);
    }

    /**
     * 账单详情--全部待缴费
     * 参数：只有小程序调用
     */
    @ReqMapping("/findBillUnPaidAll")
    public Object findBillUnPaidAll(JSONObject jsonObject,HttpServletRequest request) throws Exception {

        Token token = tokenService.getUserToken(request);
        if (!checkLogin(token)) {
            return Result.error(0, "请先登录");
        }


        String userNo = token.getUuid();
        List<Map<String,Object>> maps = new LinkedList<>();
        //跨库请求数据
        JSONArray khtIds = jsonObject.getJSONArray("khtIds");
        jsonObject.remove("token");
        if (Objects.isEmpty(khtIds)) {
            return maps;
        }
        for (Object khtId : khtIds) {
            String companyNo = (String) khtId;
            logger.info("获取住户信息，khtId:{}",khtId);

            ThreadLocalCache.current().setCorpId(companyNo);
            JSONObject residentHouseResult = doveClient.post("/crm/resident/service/getResidentHouseList", (http) -> {
                JSONObject body = new JSONObject();
                body.put("pageNo", 1);
                body.put("pageSize",2000);
                body.put("houseType","1");
                body.put("residentNo",userNo); //只有小程序
                body.put("bindType", Arrays.asList("1")); //激活的
                http.setBody(body.toJSONString());
            });

            List<Object> houseList = new LinkedList<>();
            List<Object> billAmount = new LinkedList<>();

            if (residentHouseResult.getIntValue("code") != 200) {
                logger.error("获取住户信息失败{}",residentHouseResult);
                continue;
            }

            JSONArray residentHouseList = residentHouseResult.getJSONObject("data").getJSONArray("list");
            for (int i = 0; i < residentHouseList.size(); i++) {

                JSONObject obj = residentHouseList.getJSONObject(i);
                houseList.add(obj);
                jsonObject.put("houseNo", obj.getString("houseNo"));
                //查询账单金额
                List<ChargeBillItemAppDTO> objs = chargeBillItemsService.findBillAmount(jsonObject, token);
                if (Objects.nonEmpty(objs)) {
                    billAmount.add(objs);
                }
            }

            Map<String, Object> map = new HashMap<>();
            map.put("companyNo", companyNo);
            map.put("billAmount", billAmount);
            map.put("houseList", houseList);
            map.put("residentHouseList", residentHouseList);
            maps.add(map);
        }
        return maps;
    }

    /**
     * 账单详情--全部待缴费
     * 参数：只有小程序调用
     */
    @ReqMapping("/findBillUnPaidApp")
    public Object findBillUnPaidApp(JSONObject jsonObject, Token token) throws Exception {

        List<ChargeBillItems> itemsList = jdbcSession.findArray(ChargeBillItems.class)
                .eq(jsonObject,"userNo")
                .eq("deleted", false)
                .in("billStatus", ChargeBillStatusEnum.BILL_WAIT_PAID.getId())
                .groupBy("houseNo").exe();

        Map<String, Object> map = new HashMap<>();
        map.put("houseList", itemsList);
        return map;
    }



    /**
     * 账单详情--每个月剩余待缴费(汇总接口)
     * 参数： 用户id，年月，
     */
    @ReqMapping("/findUserBillUnPaid")
    public Object findUserBillUnPaid(JSONObject jsonObject,Token token) throws Exception {

        return chargeBillItemsService.findBillUser(jsonObject,token);
    }

    /**
     * 账单详情--每个月剩余待缴费(汇总接口)-账单金额
     * 参数： 用户id，年月，
     */
    @ReqMapping("/findUserBillAmount")
    public Object findUserBillAmount(JSONObject jsonObject,Token token) throws Exception {

        return chargeBillItemsService.findList(jsonObject);
    }

    /**
     * 账单详情--每个月剩余待缴费(汇总接口)--退款金额
     * 参数： 用户id，年月，
     */
    @ReqMapping("/findUserBillRefund")
    public Object findUserBillRefund(JSONObject jsonObject,Token token) throws Exception {

        return chargeBillItemsService.findBillUser(jsonObject,token);
    }









    /**
     * 账单详情（根据住户号统计该用户所有月份的待缴费账单信息）
     * @param jsonObject
     * @return
     * jian Ye
     */
    @ReqMapping("/house/all/month/unpaid")
    public Object houseAllUnpaidMonth(JSONObject jsonObject){
        return chargeBillHouseService.houseAllUnpaidMonth(jsonObject);
    }


    /**
     * 账单详情（根据住户号和年份统计该用户当年所有未缴费和缴费账单列表信息）
     * @param jsonObject
     * @return
     * jian Ye
     */
    @ReqMapping("/house/year")
    public Object houseYear(JSONObject jsonObject){
        return chargeBillHouseService.houseYear(jsonObject);
    }


    /**
     * 账单详情（根据住户号和年月统计该用户账单总金额和未缴、已缴、退款信息）
     * @param jsonObject
     * @return
     */
    @ReqMapping("/house/year/month")
    public Object houseYearMonth(JSONObject jsonObject){
        return chargeBillHouseService.houseYearMonth(jsonObject);
    }


    /**
     * 账单详情（根据住户号和其他条件查询账单明细分页）
     * @param jsonObject
     * @return
     * jian Ye
     */
    @ReqMapping("/house/details")
    public Object houseDetailsPage(JSONObject jsonObject) throws Exception {
        return chargeBillItemsService.findPage(jsonObject);
    }


    private boolean checkLogin(Token token) {
        if (Objects.isNull(token) || Objects.isEmpty(token.getUuid())) {
            return false;
        }
        return true;
    }
}
